﻿using System;
using System.Windows.Forms;
using Bioinformatics.Algorithms;
using Bioinformatics.Types;
using Bioinformatics.Utilities;
using Bioinformatics.Controls;

namespace PsomlGui
{
    public partial class MainForm : Form
    {
        private readonly PsomlBenchmarkManager psomlBenchmarkManager;

        private GeneticSequenceCollection _geneticSequenceCollection = new GeneticSequenceCollection();

        public MainForm()
        {
            InitializeComponent();
            var graphForm = new RealTimeGraphViewer();

            //create benchmarks and add to combo box
            psomlBenchmarkManager =
                new PsomlBenchmarkManager(new IBenchmarkable[] {new PsomlCuda(), new PsomlNative(), new PsomlParallelFx()})
                    {
                        CurrentConfiguration = PsomlConfiguration.ImportFromFile(Properties.Settings.Default.CudaArgumentsOutputFilePath)
                    };
            psomlBenchmarkManager.BenchmarkComplete += enableGui;

            foreach (string algorithmName in psomlBenchmarkManager.CurrentBenchmarks.Keys)
                uxBenchmarkList.Items.Add(algorithmName);
            uxBenchmarkList.SelectedIndex = 0;
        }

        private void updateAvailableSequences()
        {
            //clear all elements from the checked list box
            uxAvailableSequences.Items.Clear();
            //re-add all elements and any extra
            foreach (var species in _geneticSequenceCollection.Keys)
                uxAvailableSequences.Items.Add(species, _geneticSequenceCollection[species].Database);
        }

        private void uxPreferencesButton_Click(object sender, EventArgs e)
        {
            var preferencesForm = new PreferencesForm();
            preferencesForm.ShowDialog();
        }

        private void enableGui(object sender, EventArgs e)
        {
            uxToolStrip.Enabled = true;
        }

        private void uxAddManualSequenceButton_Click(object sender, EventArgs e)
        {
            var manualSequenceAdditionForm = new ManualSequenceAdditionForm();
            if (manualSequenceAdditionForm.ShowDialog() == DialogResult.OK)
            {
                _geneticSequenceCollection.Add(manualSequenceAdditionForm.ManualGeneticSequenceEntry.ToString(), manualSequenceAdditionForm.ManualGeneticSequenceEntry);
                updateAvailableSequences();
            }
        }

        private void uxOpenButton_Click(object sender, EventArgs e)
        {
            var openFileDialog = new OpenFileDialog
                                     {
                                         Filter = "Genetic Sequence Collection *.gsc|*.gsc"
                                     };
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                _geneticSequenceCollection = GeneticSequenceCollection.ImportCollectionFromFile(openFileDialog.FileName);
                updateAvailableSequences();
            }
        }

        private void uxRemoveSequenceButton_Click(object sender, EventArgs e)
        {
            foreach (var selectedItem in uxAvailableSequences.SelectedItems)
                _geneticSequenceCollection.Remove(((ListViewItem)selectedItem).Text);

            updateAvailableSequences();
        }

        private void uxRunBenchmark_Click(object sender, EventArgs e)
        {
            //disable tool strip UI
            uxToolStrip.Enabled = false;
            //begin benchmark using the manager
            psomlBenchmarkManager.BeginBenchmark(uxBenchmarkList.SelectedItem.ToString());
        }

        private void uxSaveButton_Click(object sender, EventArgs e)
        {
            var saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Genetic Sequence Collection *.gsc|*.gsc";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
                _geneticSequenceCollection.ExportCollectionToFile(saveFileDialog.FileName);
        }

        private void uxSettingsButton_Click(object sender, EventArgs e)
        {
            var preferencesForm = new PreferencesForm
                                      {
                                          EntrezBrowserExecutablePath =
                                              Properties.Settings.Default.EntrezBrowserExecutablePath,
                                          EntrezBrowserOutputFilePath =
                                              Properties.Settings.Default.EntrezBrowserOutputFilePath,
                                          CudaExecutableFilePath = Properties.Settings.Default.CudaExecutableFilePath,
                                          CudaArgurmentsOutputFilePath =
                                              Properties.Settings.Default.CudaArgumentsOutputFilePath,
                                          PsomlConfiguration = psomlBenchmarkManager.CurrentConfiguration
                                      };
            if(preferencesForm.ShowDialog() == DialogResult.OK)
            {
                Properties.Settings.Default.EntrezBrowserExecutablePath = preferencesForm.EntrezBrowserExecutablePath;
                Properties.Settings.Default.EntrezBrowserOutputFilePath = preferencesForm.EntrezBrowserOutputFilePath;
                Properties.Settings.Default.CudaExecutableFilePath = preferencesForm.CudaExecutableFilePath;
                Properties.Settings.Default.CudaArgumentsOutputFilePath = preferencesForm.CudaArgurmentsOutputFilePath;
                psomlBenchmarkManager.CurrentConfiguration = preferencesForm.PsomlConfiguration;
                psomlBenchmarkManager.CurrentConfiguration.ExportToCafFile(Properties.Settings.Default.CudaArgumentsOutputFilePath);
                Properties.Settings.Default.Save();
            }
        }

        private void uxLaunchEntrezBrowser_Click(object sender, EventArgs e)
        {
            var entrezBrowserLauncherForm = new EntrezBrowserLauncherForm{EntrezBrowserExecutablePath = Properties.Settings.Default.EntrezBrowserExecutablePath};
            if(entrezBrowserLauncherForm.ShowDialog() == DialogResult.OK)
            {
                _geneticSequenceCollection = GeneticSequenceCollection.ImportCollectionFromFile(Properties.Settings.Default.EntrezBrowserOutputFilePath);
                updateAvailableSequences();
            }
        }

        private void uxRunOptimization_Click(object sender, EventArgs e)
        {
            psomlBenchmarkManager.BeginBenchmark(uxBenchmarkList.SelectedItem.ToString());
        }
    }
}